import com.adobe.serialization.json.JSON;

import flash.events.*;
import flash.events.KeyboardEvent;
import flash.system.Security;
import flash.ui.Keyboard;

import mx.charts.LegendItem;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.core.FlexGlobals;
import mx.core.UIComponent;
import mx.events.SliderEvent;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;

import org.papervision3d.cameras.Camera3D;
import org.papervision3d.events.FileLoadEvent;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.parsers.DAE;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.Viewport3D;

private var config:Object;
private var modelConfig:Object;

private var renderer:BasicRenderEngine = new BasicRenderEngine();
private var scene:Scene3D = new Scene3D();
private var camera:Camera3D = new Camera3D();
private var viewport:Viewport3D;
private var modelDisplay:DisplayObject3D;
private var model:DAE = null;

//private var model:Dae
private var defaultColour:ColorMaterial;
private var selectColour:ColorMaterial;
private var wire:WireframeMaterial = new WireframeMaterial(0x888888);
private var currSelectObject:String;

private var rotateModel:Boolean;
private var signalData:Array;
private var signalReturnCount:int;
private var signalTotalCount:int;
private var tissueList:Array;
private var signalColours:Array;
private var currLevel:String;
private var signalError:Boolean;
private var type:String;
private var view:String = "absolute";
[Bindable]
private var controlValue:Number = 0;
private var tissueSources:Object = new Object();
private var tissueLink:String;
private var maxRatio:Number;
public var rotating:Boolean = false;
[Bindable]
public var annotationlabelstring:String;
[Bindable]
private var modelPartList:ArrayCollection;
[Bindable]
private var percentageProgress:Number;//=new Number();
private var colours:Dictionary = new Dictionary()

private var pgarray:ArrayCollection=new ArrayCollection();

import mx.graphics.ImageSnapshot;
import mx.graphics.codec.JPEGEncoder;
import mx.collections.Sort;
import mx.collections.SortField;
import mx.charts.CategoryAxis;
import mx.events.IndexChangedEvent;
import mx.events.ChildExistenceChangedEvent;
import flash.media.Video;
import mx.controls.Text;

[Bindable]
private var scalexvalue:Number=2;
[Bindable]
private var scaleyvalue:Number=2;

[Bindable]
private var secondGO:Boolean=false;
[Bindable]
private  var signaltxt:String;

private var file:FileReference = new FileReference();
private function takeSnapshot(source:IBitmapDrawable):void {
	var bitmapData:BitmapData = new BitmapData(plant.width, plant.height);
	bitmapData.draw(plant,new Matrix());
	var bitmap : Bitmap = new Bitmap(bitmapData);
	var jpg:JPEGEncoder = new JPEGEncoder(100);
	var ba:ByteArray = jpg.encode(bitmapData);
	file.save(ba,input_AGI.text + '.png');
}

/**
 *  The application constructor method which establishes the stage and
 *  begins the main configuration file request.
 */
private function eplant_init() : void {
	input_AGI.text = FlexGlobals.topLevelApplication.parameters.agi;
	basicAccordion.addEventListener(Event.CHANGE,basicaccordiochange);
	// hide source labels
	lblSourceP1.visible = false;
	lblSourceP2.visible = false;
	lblSourceC1.visible = false;
	lblSourceC2.visible = false;
	lblTissueLinks.visible = false;
	//buttonRelative.enabled = false;
	//buttonRelative.enabled = false;
	ARbox.visible = false;
	
	signalLegend.direction = "vertical";
	addLegendItem(0, 0x888888, "No legend available.");
	serve_getConfigData.send();
	viewport = new Viewport3D(1000, 1000, true, true);
	
	var flexComp:UIComponent = new UIComponent();
	//mainCanvas.addChild(flexComp);
	//flexComp.addChild(viewport);
	
	
	selectColour = new ColorMaterial(0xC71901, 1, true);
	modelPartList = new ArrayCollection();
	

}

/**
 *  Determine if the user has passed a particular type or agi value
 *  in via FlashVars. This is meant to handle the new way in which the
 *  ePlant browser will be viewed.
 */
private function detectFlashVarOptions():void {
	
	// check for view type (plant view only)
	
	view =  this.currentState.toLowerCase();//FlexGlobals.topLevelApplication.parameters.view.toLowerCase();

		input_AGI.text = FlexGlobals.topLevelApplication.parameters.agi;
		
	
	serve_getConfigData.send();
	
}

/**
 *  Main configuration handle file which parses requests from the
 *  config.json file which is hard-coded into the mxml file. This request
 *  is made only once, handle_mapper_json handles non-default settings.
 */
private function handle_config_files(event:ResultEvent):void {
	
	if (event.target.url == "config.json") {
		changeStatus("Main configuration file loaded.");
		config = (JSON.decode(String(event.result)));
		if (config.modelmaps.length == 0) {
			changeStatus("No model maps were defined in the configuration file.");
		} else {
			changeZoomView();
			changeStatus("Loading " + config.modelmaps[0].name + " model configuration.");
		//	detectFlashVarOptions();
			
			
		}
	} else {
		modelConfig = (JSON.decode(String(event.result)));
		rotateModel = modelConfig.settings.rotate_model;
		loadPolFile(modelConfig.settings.webservice.policy_file);
		defaultColour = new ColorMaterial(modelConfig.settings.default_colour, 1, true);
		if (modelConfig.settings.example == null) {
			example.enabled = false;
		} else {
			example.enabled = true;
		}
		
		loadModel(modelConfig.settings.model_path);
		currLevel = modelConfig.settings.name;
		
		//initKeyFunctions()
	}
	
}

/**
 * Retrieve the sample AGI from the config file and populate the AGI box.
 */
private function populateExampleAgi():void {
	
	if (modelConfig.settings.example != undefined) {
		input_AGI.text = modelConfig.settings.example;
	}
}

/**
 * Retrieves the crossdomain file for the web-service policy file.
 */
private function loadPolFile(url:String):void {
	
	Security.loadPolicyFile(url);
}

/**
 *  Loads the main stage model data from a Collada DAE file which is 
 *  passed in as a path.
 */
private function loadModel(model_path:String):void {
	
	removeModel();
	model = new DAE(true);
	
	changeStatus("Loading " + modelConfig.settings.name + " model data.");
	model.load(model_path, new MaterialsList({ all: wire }));
	model.addEventListener(FileLoadEvent.LOAD_COMPLETE, modelLoadSuccess);
	model.addEventListener(FileLoadEvent.LOAD_PROGRESS, modelLoadProgress);
	
	//adjust_camera(modelConfig.settings.camera_position.x,
	//modelConfig.settings.camera_position.y,
	//modelConfig.settings.camera_position.z);
	
	addEventListener(Event.ENTER_FRAME, onEnterFrame);
}

/**
 *  Handles the progress loader for the model loading function.  
 */
private function modelLoadProgress(e:FileLoadEvent):void {
	
	var percentage:Number = e.bytesLoaded / e.bytesTotal;
	changeStatus("Model load and parse progress: " + (Math.round(10000 * percentage) / 100) + "%");
	//percentageProgress=Math.round(10000 * percentage)/100;
}

/**
 * Remove the model and all the modelPartsList from the stage.  
 */
private function removeModel():void {
	
	if (model != null) {
		scene.removeChild(model);
		model = null;
	}
	modelPartList = new ArrayCollection();
}

/**
 *  Adjust the camera x, y, z location.
 */
private function adjust_camera(xPos:*, yPos:*, zPos:*):void {
	if (xPos != null) { camera.x = xPos; }
	if (yPos != null) { camera.y = yPos; }
	if (zPos != null) { camera.z = zPos; }
}

/**
 *  On model loaded, begin painting each part of the model to the default
 *  colour as specified in the map-data config.
 */
private function modelLoadSuccess(e:Event):void {
	plant.visible=true;
	modelDisplay = scene.addChild(model);
	changeStatus("Model file loaded.");
	
	var settings:Object = modelConfig.settings.model_position;
	var listLabels:Array = new Array();
	var listData:Object = new Object();
	
	
	if (settings.x != null) { model.x = settings.x; }
	if (settings.y != null) { model.y = settings.y; }
	if (settings.z != null) { model.z = settings.z; }
	
	if (settings.rotationX != null) { model.rotationX = settings.rotationX; }
	if (settings.rotationY != null) { model.rotationY = settings.rotationY; }
	if (settings.rotationZ != null) { model.rotationZ = settings.rotationZ; }
	
	for (var nodeName:String in modelConfig.modelmap) {
		var objNode:Object;
		if ((objNode = model.getChildByName("COLLADA_Scene").getChildByName(nodeName))) {
			objNode.material.doubleSided = true;
			if (modelConfig.settings.default_colour != null) {
				paintObject(nodeName, defaultColour);
			}
			
			listLabels.push(modelConfig.modelmap[nodeName][0]);
			listData[modelConfig.modelmap[nodeName][0]] = nodeName;
			
		} else {
			trace("paintObject: Node object " + nodeName + " was not detected.");
			
		}
	}
	if (input_AGI.text != "") {
		submitAGI();
	}
	
	listLabels.sort();
	for (var label:String in listLabels) {
		modelPartList.addItem({label: listLabels[label], data: listData[listLabels[label]]});
		
	}
	
	
	//Here we rae going to add items to relative dropdown
	
	if(pgarray.length==0){
		//for (var objectNamess:String in modelConfig.modelmap) {
		//for(var i:int=0;i<modelConfig.modelmap[objectNames].length;i++){
		//pgarray.addItem(modelConfig.modelmap[objectNamess].toString().toLowerCase());
		for (var labels:String in listLabels) {
			pgarray.addItem({label: listLabels[labels], data: listData[listLabels[labels]]});}
		//	}//}
		pgarray.addItem({label:"Global Mean", data: "gmean"});
		relativeComboBox.dataProvider=pgarray;}
}

/**
 *  Reference and part a particular object within the Collada Scene to
 *  the specific colour material.
 */
private function paintObject(nodeName:String, material:*):void {
	if (model.getChildByName("COLLADA_Scene").getChildByName(nodeName)) {
		model.getChildByName("COLLADA_Scene").getChildByName(nodeName).material = material;
	}
	
	if(nodeName=="mature_leaves"){
		plant.mature_leaves0.color=material.fillColor;
		plant.mature_leaves1.color=material.fillColor;
		plant.mature_leaves2.color=material.fillColor;
		plant.mature_leaves3.color=material.fillColor;
		plant.mature_leaves4.color=material.fillColor;
		plant.mature_leaves5.color=material.fillColor;
		plant.mature_leaves6.color=material.fillColor;
		plant.mature_leaves7.color=material.fillColor;
		plant.mature_leaves8.color=material.fillColor;
		plant.mature_leaves9.color=material.fillColor;
		plant.mature_leaves10.color=material.fillColor;
		plant.mature_leaves11.color=material.fillColor;
		plant.mature_leaves12.color=material.fillColor;
		plant.mature_leaves13.color=material.fillColor;
		
		
	}
	if(nodeName=="young_leaves"){
		plant.young_leaves0.color=material.fillColor;
		plant.young_leaves1.color=material.fillColor;
		plant.young_leaves2.color=material.fillColor;
		plant.young_leaves3.color=material.fillColor;
		plant.young_leaves4.color=material.fillColor;
		plant.young_leaves5.color=material.fillColor;
		plant.young_leaves6.color=material.fillColor;
		plant.young_leaves7.color=material.fillColor;
		plant.young_leaves8.color=material.fillColor;
		plant.young_leaves9.color=material.fillColor;
		plant.young_leaves10.color=material.fillColor;
		plant.young_leaves11.color=material.fillColor;
		plant.young_leaves12.color=material.fillColor;
		plant.young_leaves13.color=material.fillColor;
		plant.young_leaves14.color=material.fillColor;
	}
	if(nodeName=="roots"){
		plant.uproots0.color=material.fillColor;
		plant.uproots1.color=material.fillColor;
		plant.uproots2.color=material.fillColor;
		plant.uproots3.color=material.fillColor;
		plant.uproots4.color=material.fillColor;
		plant.uproots5.color=material.fillColor;
		plant.roots0.color=material.fillColor;
		plant.roots1.color=material.fillColor;
		plant.roots2.color=material.fillColor;
		plant.roots3.color=material.fillColor;		
	}
	if(nodeName=="internode"){
		plant.intermode.color=material.fillColor;
	}
	if(nodeName=="node"){
		plant.node.color=material.fillColor;	
	}
	//nodeName[i].color=material.fillColor;
	
}

private function getExpressionData(primaryGene:String, sampleId:String):void {
	var objSend:Object = new Object();
	objSend.primaryGene = primaryGene;
	objSend.sample = sampleId;
	serve_getExpressionData.send(objSend);
}

/**
 * This function resets the legend and accounts for a strange directional
 * issue which dissallows the legend to display correctly.
 */
private function resetLegend():void {
	signalLegend.removeAllChildren();
}

/**
 *  Draws a legend for the current signal data according to the number of
 *  legend boxes to show, plus an extra gray box.
 *  TO-DO: Clean up this function ie. adds two items to numItem and could
 *         be done better overall.
 */
private function populateLegend(numItems:int, maxValue:Number):void {
	var perItem:Number = roundNumber(maxValue / numItems, 2);
	var count:Number = maxValue;
	var intensity:Number;
	var paintColour:uint;
	var redVal:uint;
	
	var stage:Array = new Array(11);
	var stages:int = 11;
	var s:String = ""
	
	resetLegend();
	
	
	if (view == "relative") {
		var signalDelta:Number = -2*maxRatio;
		var signalGrad:Number = -Math.abs(signalDelta) / (stages - 1);
		var signal:Number = maxRatio;
		
		for (var k:int = 0; k < stages; k++) {
			
			// Ensure True Minimum
			if (k == stages - 1) {
				signal = -1 * maxRatio;
			}
			
			intensity = signal * 256.0 / maxRatio
			intensity = clamp(intensity, -255, 255)
			
			if (k == 0) {
				var fold:Number = Math.pow(2, signal)
				s = "  " + fold.toString().substr(0,4) +  "-fold"
			} else {
				s = ""    
			}
			
			if (signal > 0) {
				// Yellow (neutral) to red
				paintColour = getHexFromRGB(255, 255 - intensity, 0)
			} else {
				// Yellow to blue
				paintColour = getHexFromRGB(255 + intensity, 255 + intensity, - intensity)
			}
			addLegendItem(k, paintColour, String(roundNumber(signal, 2)) + s);
			signal += signalGrad;
		}
	} else {
		
		for (var i:int = 0; i < numItems; i++) {
			intensity = Math.floor(count * 256.0 / maxValue);
			if (count == maxValue) {
				redVal = 0;
				
			} else {
				redVal = 255 - intensity;
				//Alert.show(redVal.toString());
			}
			
			if (count >= 0) {
				paintColour = getHexFromRGB(255, redVal, 0);
			} else {
				paintColour = getHexFromRGB(Math.min(255, 255 + intensity), Math.min(255, 255 + intensity), -intensity);
			}
			
			if ((currLevel == "Cell Level") && (roundNumber(count, 2) == 7)) { 
				addLegendItem(i, paintColour, String(roundNumber(count, 2)) + " - high confidence in localization "); // subcellular localization
			} else if ((currLevel == "Cell Level") && (roundNumber(count, 2) == 1)) {
				addLegendItem(i, paintColour, "1 - low confidence in localization");
			}else {
				if(count.toString()!='0'){
					signalLegend.visible=true;
					addLegendItem(i, paintColour, String(roundNumber(count, 2)));}else{
						addLegendItem(i, paintColour, String(roundNumber(count, 1)))
						signalLegend.visible=false;
						changeStatus("Wrong POPTR ID ");
					}
			}
			count -= perItem;
		}
		if (currLevel != "Cell Level") {
			addLegendItem(i, paintColour, "0");
		}
	}
}


private var aTemp:Array= new Array();
private var expall:Number;
private var newonex:Number;

private var averageArray:Array=new Array();
private var expaveragevalue:Number;
[Bindable]
private var averageArrayfinal:Array=new Array();

private var exprDatachartfinal:Object=new Object();


public function onClickbutton():void{
	
	averageArrayfinal=new Array();
	averageArray=new Array();
	aTemp= new Array();
	//signalTotalCount=0;
	//modelPartList = new ArrayCollection();
	modelPartList.removeAll();
	//exprDatachartfinal=new Object();
	expall=0;
	expaveragevalue=0;
	newonex=0;
	submitAGI();
	
	//aTemp=null;
}
/**
 *  A function that recurses through all the mapped tissue function and requests
 *  the data from the specified web service.
 */
private function submitAGI():void {
	signalReturnCount = 0;
	// I change default signalTotalCount 1 to zero and commented control http send this is for percentage
	signalTotalCount  = 0;
	signalData = new Array();
	
	if (currLevel == "Cell Level") {
		changeStatus("Collecting " + input_AGI.text + " product localisation data.");
		txtPlant.text = "";
		lblSourceC1.label = "SUBA record for " + input_AGI.text + ".";
		lblSourceC1.visible = true;
		lblSourceC2.visible = true;
	} else if (currLevel == "Plant Level") {
		changeStatus("Collecting " + input_AGI.text + " expression data.");
		txtPlant.text = "GCOS expression level\nTGT value = 100 units\nBackground ~ 20 units";
		lblSourceP1.label = "Populus eFP Browser data for " + input_AGI.text + ".";
		lblSourceP1.visible = true;
		lblSourceP2.visible = true;
		ARbox.visible = true;
	} else if (currLevel == "Tissue Level") {
		changeStatus("Collecting " + input_AGI.text + " expression data.");
		txtPlant.text = "GCOS expression level\nTGT value = 100 units\nBackground ~ 20 units";
		lblTissueLinks.visible = true;
		lblTissueLinks.text = "Click on a sample name in the Sample List above\n for references linked to data source descriptions.";
		ARbox.visible = true;
	}
	
	if (currLevel == "Plant Level" || currLevel == "Tissue Level") {
		if (input_AGI.text.indexOf(".") != -1) {
			input_AGI.text = input_AGI.text.substr(0, input_AGI.text.indexOf("."));
		}
		var base:String = modelConfig.settings.webservice.src + "?primaryGene=" + input_AGI.text;
		signalError = false;
		//var dparray:ArrayCollection;
		for (var objectName:String in modelConfig.modelmap) {
			// The first item in the list is the tissue name, start from 1 and down
			var samplePos:int = 1
			if (currLevel == "Tissue Level") {
				samplePos=3;
				tissueSources[objectName] = modelConfig.modelmap[objectName][1] + "URL" + modelConfig.modelmap[objectName][2]
			}
			if(objectName!="control"){
				for (samplePos; samplePos < modelConfig.modelmap[objectName].length; samplePos++) {
					serve_getExpressionData.url = base + "&sample=" + modelConfig.modelmap[objectName][samplePos].toLowerCase();
					serve_getExpressionData.send();
					signalTotalCount++;
					//dparray.addItem(modelConfig.modelmap[objectName][samplePos].toLowerCase());
				}}
			//relativeComboBox.dataProvider=dparray;
		}
		// Request the control sample as well
		//if(relativeComboBox.selectedLabel==""){
		//serve_getExpressionData.url = base + "&sample=" + modelConfig.settings.control_sample.toLowerCase();
		//}else{
		//serve_getExpressionData.url = base + "&sample=" + relativeComboBox.selectedLabel.toLowerCase();//modelConfig.settings.control_sample.toLowerCase();
		//}
		//Alert.show(serve_getExpressionData.url.toString());
		//	serve_getExpressionData.send();
		//relativeComboBox.dataProvider=modelConfig.modelmap[0];
		/*for (var objectNames:String in modelConfig.modelmap) {
		for(var i:int=0;i<modelConfig.modelmap[objectNames].length;i++){
		relativeComboBox.dataProvider=modelConfig.modelmap[objectName][i].toString());
		}}*/
		//serve_getExpressionDataAnnotation.url = base + "&sample=" + modelConfig.settings.control_sample.toLowerCase();
		//serve_getExpressionDataAnnotation.send();
	} else if (currLevel == "Cell Level") {
		if (input_AGI.text.indexOf(".") == -1) {
			input_AGI.text = input_AGI.text + ".1";
		}
		serve_getExpressionData.url = modelConfig.settings.webservice.src + "?agi=" + input_AGI.text;
		serve_getExpressionData.send();
	}
	probeidtxt=input_AGI.text;
	basicAccordion_clickHandler();
	
}




/**
 *  Retrieve the expression data results from the web service handler.
 */
private function expressionDataResult(event:ResultEvent):Boolean {
	// Cancel executing the request if there was an error detected. Ideally this should
	// be done at the beginning of the signal requests so that it doesn't make more HTTP
	// requests than necessary.
	if (signalError) { return false; }
	
	var exprData:Object = JSON.decode(String(event.result));
	exprDatachartfinal = exprData;
	//Alert.show(exprData.toString());
	
	if (currLevel == "Plant Level" || currLevel == "Tissue Level") {
		if (exprData["error"] == undefined) {
			//for (var value:String in exprData) {
			//;
			//shows up as ATGE_CTRL_7
			//Alert.show(exprData[name].toString());
			
			//}
			
			// A loop is used in case a future script will provide more sample details to record
			for (var name:String in exprData) {
				var numberValue:Number = new Number(exprData[name]);
				//exprData[name]=numberValue.toFixed(2);
				var expTemp:Number=exprData[name];
				expall+=numberValue;
				aTemp.push({data:expTemp.toFixed(2),label:name});
				
				signalData[name] = exprData[name];
				//shows up as ATGE_CTRL_7
				//Alert.show(signalData[name].toString());
			}
			
			//Check all the array items filled
			if(aTemp.length==signalTotalCount){
				expaveragevalue=expall/signalTotalCount;
			}
			//If avarage value not zero we use new avarage value for further calculations
			if(expaveragevalue!=0){
				newonex=expaveragevalue;
				callForMean();
			}
			
			if(aTemp.length==signalTotalCount  ){
				
				modelPartList=new ArrayCollection(aTemp);
				sortCollection(modelPartList);
			}
			modelPartList=modelPartList;
			trace("name"+signalData[relativeComboBox.selectedLabel]);
			//	trace("name"+exprData[value]);
			
		}/*	else if(exprData[name]==''){
			Alert.show("imhere");
			
			}*/
		//aTemp=new Array();
			
		else  {
			signalError = true;
			changeStatus("There was an error requesting " + input_AGI.text);
			return false;
		}
		signalReturnCount++;
		var percent:int = Math.round(signalReturnCount / signalTotalCount * 100);
		if (percent == 100) {
			changeStatus("Signal data retrieval complete.");
			progressBar.setProgress(percent , 100);
			progressBar.visible=false;
			calculateSignals();
			paintSignalData();
			populateLegend(modelConfig.settings.legend_items, maxSignal());
		} else {
			changeStatus("Retrieved " + percent + "% of signal data.");
			progressBar.visible=true;
			progressBar.setProgress(percent , 100);
		}
	} else {
		changeStatus("SUBA data retrieval complete, processing results.");
		calculateSUBAData(exprData);
		paintSUBAScoreData();
		populateLegend(modelConfig.settings.legend_items, modelConfig.presence_weight.max_score);
		
		// changed populateLegend(8 ... to modelConfig.settings.legend_items)
	}
	return true;
}


private function callForMean():void{
	for(var z:int=0;z<aTemp.length;z++){
		averageArrayfinal.push({afName:aTemp[z].label,afData:newonex.toFixed(2)});
	}
	averageArrayfinal=averageArrayfinal;
}

private function sortCollection(arrayCollection : ArrayCollection) : void
{
	//Create the sort field
	var dataSortField:SortField = new SortField();
	
	//name of the field of the object on which you wish to sort the Collection
	dataSortField.name = "label";
	dataSortField.caseInsensitive = true;
	
	/*
	If you wish to perform numeric sort then set:
	dataSortField.numeric = true;
	*/
	
	//create the sort object
	var dataSort:Sort = new Sort();
	dataSort.fields = [dataSortField];
	
	arrayCollection.sort = dataSort;
	//refresh the collection to sort
	arrayCollection.refresh();
	
	
}

private function expressionDataannotationResult(event:ResultEvent):Boolean {
	// Cancel executing the request if there was an error detected. Ideally this should
	// be done at the beginning of the signal requests so that it doesn't make more HTTP
	// requests than necessary.
	if (signalError) { return false; }
	
	//var exprData:Object = ;
	//Alert.show(;
	//	}
	var exprData:Object = JSON.decode(String(event.result.toString()));
	if (currLevel == "Plant Level" || currLevel == "Tissue Level") {
		if (exprData["error"] == undefined) {
			//for (var value:String in exprData) {
			//;
			//shows up as ATGE_CTRL_7
			//	Alert.show(exprData.value);
			
			//}
			if(exprData.gene.toString()!="" && exprData.besthit.toString()!=""){
				//genelabel.visible=true;
				//besthitlabel.visible=true;
				//annotationlabel.visible=true;
				//genelabel.text="Gene: "+exprData.gene.toString();
				//besthitlabel.text="Best Hit: "+exprData.besthit.toString();
				//var myArray1:Array = new Array(exprData);
				//for(var i:int=0;i<myArray1.length;i++){
				var newonee:String=new String(exprData.annotation.toString().charAt(0).toUpperCase()+exprData.annotation.substr(1));
				
				annotationlabel.text="Annotation: "+newonee;//exprData.annotation.toString();
			}else{
				genelabel.visible=false;
				besthitlabel.visible=false;
				annotationlabel.visible=false;	
				
			}
			//	var rawData:String = String(event.result);
			//	var arr:Array = (JSON.decode(rawData).items as Array);
			// A loop is used in case a future script will provide more sample details to record
			//for (var name:String in exprData) {
			//signalData[name] = exprData[name];
			//annotationlabelstring=signalData[name].toString();
			//	Alert.show(arr.length.toString());
			//}
			
			
		}}
	
	
	return true;
}


/**
 * Handle failed HTTPService component requests.
 */
private function expressionDataResultFault(event:FaultEvent):Boolean {
	//Alert.show(event.fault.content.toString());
	changeStatus("There was an error loading webservice data, please try again.");
	return true;
}

/**
 *  Run through all the signal data and calculate the information for tissue
 *  values to use.
 */
private function calculateSignals():void {
	tissueList = new Array();
	
	for (var objectName:String in modelConfig.modelmap) {
		tissueList[objectName] = { 'samples': new Array(),
			'mean':    0,
			'signal':  0,
			'stddev':  0 };
		
		var samplePos:int = 1
		if (currLevel == "Tissue Level") { samplePos=3 } // adjust for added sources
		
		for (samplePos; samplePos < modelConfig.modelmap[objectName].length; samplePos++) {
			var val:Number = signalData[modelConfig.modelmap[objectName][samplePos].toLowerCase()];
			tissueList[objectName].samples.push(val);
		}
		
		// This should be adjusted in the future
		tissueList[objectName].mean   = average(tissueList[objectName].samples);
		tissueList[objectName].signal = tissueList[objectName].mean;
		
		if (objectName.toLowerCase() == relativeComboBox.selectedItem.data ) {
			
			if(relativeComboBox.selectedItem.data != "gmean"){
				controlValue =tissueList[relativeComboBox.selectedItem.data].signal;//signalData[relativeComboBox.selectedLabel];// tissueList[objectName].signal
				//if(controlValue.toString()=="NaN"){
				//Alert.show(controlValue.toString());
				//controlValue =tissueList[relativeComboBox.selectedLabel].signal;
				//}
			}/*else{
			controlValue=57;
			Alert.show(controlValue.toString());
			}*/
			
			if(secondGO==true ){
				var num:Number=new Number(signaltxt)
					num=Math.exp(num);
				if(num>0){
					var newnumber:Number;
					controlValue=num;
					//newnumber=Math.log(controlValue);
					Alert.show(controlValue.toString());
					secondGO=false;}
			}else{
				signaltxt=controlValue.toFixed(2).toString();
			}
			
		}
		
		
	}	
	if(relativeComboBox.selectedItem.data == "gmean"){
		controlValue=newonex;
		signaltxt=controlValue.toFixed(2).toString();
		//Alert.show(controlValue.toString());	
	}
}

/**
 *  Run through all the SUBA signal data and calculate the information for tissue
 *  values to use.
 */
private function calculateSUBAData(exprData:Object):void {
	
	tissueList = new Array();
	var score:int;
	for (var objectName:String in modelConfig.modelmap) {
		tissueList[objectName] = { 'score': 0 };
		var cellPart:String = modelConfig.modelmap[objectName][1];
		tissueList[objectName].score += calculatePresence(cellPart, exprData.predicted, modelConfig.presence_weight.experimental.locations)  * modelConfig.presence_weight.experimental.score;
		tissueList[objectName].score += calculatePresence(cellPart, exprData.predicted, modelConfig.presence_weight.computational.locations) * modelConfig.presence_weight.computational.score;
		tissueList[objectName].score += calculatePresence(cellPart, exprData.observed, modelConfig.presence_weight.experimental.locations)   * modelConfig.presence_weight.experimental.score;
		tissueList[objectName].score += calculatePresence(cellPart, exprData.observed, modelConfig.presence_weight.computational.locations)  * modelConfig.presence_weight.computational.score;
	}
}

/**
 *  Calculate occurences of a particular item in the provided array list.
 */
private function calculatePresence(comp:String, subaArray:Array, haystack:Array):int {
	
	var count:int = 0;
	for (var i:String in subaArray) {
		if (subaArray[i][0] == comp) {
			if (subaArray[i][1].indexOf(haystack)) {
				count++;
			}
		}
	}
	return count;
}

/**
 *  Iterate through the available signal data and paint it onto the PLAMT itself.
 */
private function paintSignalData():void {
	
	if (view == "relative") {  // default is absolute, so ok for views without relative renders
		
		var maxR:Number = maxSignal();
		maxRatio = 0;
		
		for (var nameR:String in tissueList) {
			var ratioLog2:Number;
			var signalR:Number = tissueList[nameR].signal;
			var paintColourR:uint;
			
			if (signalR == 0 || controlValue == 0) {
				ratioLog2 = 0;
			} else {
				ratioLog2  = Math.log(signalR / controlValue) / Math.log(2)
			}
			
			var ratio:Number = ratioLog2 / Math.log(maxR)
			
			// store the max abs ratio for legend
			if (Math.abs(ratioLog2) > maxRatio) {
				maxRatio = Math.abs(ratioLog2);
			}
			
			var intensityR:Number = clamp(Math.floor(256 * ratio), -255, 255)
			
			if (intensityR > 0) {
				paintColourR = getHexFromRGB(255, 255 - intensityR, 0);
			} else {
				paintColourR = getHexFromRGB(255 + intensityR, 255 + intensityR, -intensityR)
			}
			
			paintObject(nameR, new ColorMaterial(paintColourR));
		}
	} else {
		
		var Arr:Array = new Array();
		
		var max:Number = maxSignal();
		for (var name:String in tissueList) {
			var intensity:uint = Math.floor(tissueList[name].signal * 256.0 / max);
			var paintColour:uint;
			var redVal:uint;
			
			
			
			if (tissueList[name].signal == max) {
				redVal = 0;
			} else {
				redVal = 255 - intensity;
			}
			
			if (tissueList[name].signal > 0) {
				paintColour = getHexFromRGB(255, redVal, 0);
			} else {
				
				paintColour = getHexFromRGB(255 + intensity, redVal, - intensity);
				//Alert.show(paintColour.toString());
			}
			
			trace("max "+max);
			trace("intensity "+intensity);
			trace("paintColour "+paintColour);
			trace("redVal "+redVal);
			trace("name "+name);
			
			
			
			if(intensity.toString()!='0'){
				
				paintObject(name, new ColorMaterial(paintColour));
			}else{
				//Alert.show("wrong Poptr ID");
				//	resetLegend();
			}
			
		}
		
	}
	
	changeStatus("Model paint rendering complete.");
}

/**
 *  Iterate through the available signal data and paint it onto the CELL itself.
 */
private function paintSUBAScoreData():void {
	
	var max:Number = modelConfig.presence_weight.max_score;
	for (var name:String in tissueList) {
		var intensity:uint = Math.floor(tissueList[name].score * 256.0 / max);
		var paintColour:*;
		var redVal:uint;
		
		if (tissueList[name].score == 0) {
			paintColour = new WireframeMaterial(0xcccccc);
		} else {
			if (tissueList[name].score == max) {
				redVal = 0;
			} else {
				redVal = 255 - intensity;
			}
			if (tissueList[name].intensity > 0) {
				paintColour = new ColorMaterial(getHexFromRGB(255, redVal, 0));
			} else {
				paintColour = new ColorMaterial(getHexFromRGB(255 + intensity, redVal, - intensity));
			}
		}
		paintObject(name, paintColour);
		
	}
	changeStatus("Model paint rendering complete.");
}

/**
 *  A static function which rotates is called on every frame to re-draw the model
 *  and stage details.
 */
private function onEnterFrame(event:Event):void {
	
	if (rotateModel && modelConfig.settings.rotate_speed != null) {
		model.rotationY += modelConfig.settings.rotate_speed;
	}
	renderer.renderScene(scene, camera, viewport);
	
}

private function subaURL():void {
	
	var URL:String = "http://www.plantenergy.uwa.edu.au/applications/suba/flatfile.php?id=" + input_AGI.text;
	navigateToURL(new URLRequest(URL), "_blank");
}

private function eFPURL():void {
	
	var URL:String = "http://130.239.72.85/eFPSingle/efpWeb.cgi";//?modeInput=Absolute&primaryGene=" + input_AGI.text;
	navigateToURL(new URLRequest(URL), "_blank");
}

private function tissueURL():void {
	
	navigateToURL(new URLRequest(tissueLink), "_blank");
}

private function absoluterelativecheck_changeHandler(event:Event):void
{
	if(absoluterelativecheck.selection.label=="Relative"){
		relativeBox.visible=true;
		view='relative';
		submitAGI();
	}else{
		relativeBox.visible=false;
		//gobt.visible=false;
		view='absolute';
		submitAGI();
	}
}



private function basicaccordiochange(event:Event):void{
	if(this.width<1800){
	if(basicAccordion.selectedIndex>0){
		plant.right=0;	
		//accordioncomponent.height=400;	
	}else{
		plant.right=(this.width-plant.width*.8)/2
		
	//	Alert.show(this.parentApplication.width.toString());	
	//	Alert.show('2'+this.parentDocument.width.toString());
		//Alert.show(.toString());
	}
//	accordioncomponent.height=300;	
	}
	//Alert.show(.toString());
}


private function helpbtn_clickHandler(event:MouseEvent):void
{
	var URL:String = "http://screencast.com/t/bMzMMd69Ysqq";//?modeInput=Absolute&primaryGene=" + input_AGI.text;
	navigateToURL(new URLRequest(URL), "_blank");
}

private function gotoHome(event:MouseEvent):void
{
	
	var URL:String = "http://130.239.72.85/popgenie2/";//?modeInput=Absolute&primaryGene=" + input_AGI.text;
	navigateToURL(new URLRequest(URL), "_self");
}




protected function label1_clickHandler(event:MouseEvent):void
{
	input_AGI.text="POPTR_0001s00350";
}


protected function zoominEvent(event:MouseEvent):void
{
	plant.groupPlant.scaleX=2;
	plant.groupPlant.scaleY=2;
	plant.right=(this.width-plant.width*.8)/2
	//plant.x=200;

	
}

protected function zoomoutEvent(event:MouseEvent):void
{
	plant.groupPlant.scaleX=1.5;
	plant.groupPlant.scaleY=1.5;
	plant.right=0;
	//plant.x=0;
	

}
//////////////////////////////////////////NEW
import com.adobe.serialization.json.JSON;

import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.events.FlexEvent;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;

import vo.ValueObjects;
[Bindable]
private var dto:ValueObjects=new ValueObjects();
[Bindable]
public var probeidtxt:String= new String();
[Bindable]
public var averageArrayfinals:Array=new Array();
[Bindable]
public var modelPartLists:ArrayCollection=new ArrayCollection();



protected function serve_getExpressionData_resultHandler(event:ResultEvent):void
{
	
	
	// TODO Auto-generated method stub
	//if (signalError) { return false; }
	var exprData:Object = JSON.decode(String(event.result.toString()));
	if (exprData["error"] == undefined) {
		dto=new ValueObjects();
		if(exprData.Cromosome!=null){
			dto.Cromosome=exprData.Cromosome.toString();
		}
		
		if(exprData.PeptideName!=null){
			dto.PeptideName=exprData.PeptideName.toString();
		}
		
		if(exprData.transcriptstop!=null){
			dto.transcriptstopVO=exprData.transcriptstop.toString();
		}
		
		if(exprData.transcriptstart!=null){
			dto.transcriptstartVO=exprData.transcriptstart.toString();
		}
		
		if(exprData.strand!=null){
			dto.strandVO=exprData.strand.toString();
		}
		
		if(exprData.GO!=null){
			dto.GO=exprData.GO.toString();
		}
		
		if(exprData.PAC!=null){
			dto.PAC=exprData.PAC.toString();
		}
		
		
		if(exprData.peptideSeq!=null){
			dto.peptideSeq=exprData.peptideSeq.toString();
		}
		
		if(exprData.transcriptSeq!=null){
			dto.transcriptSeqtxtVO=exprData.transcriptSeq.toString();
		}
		if(exprData.cdsSeq!=null){
			dto.cdsSeqtxtVO=exprData.cdsSeq.toString();
		}
		//dto.synonymsVO=exprData.synonyms.toString();
	}else{
		
	}
	//return true;
}


protected function serve_getExpressionData_faultHandler(event:FaultEvent):void
{
	// TODO Auto-generated method stub
	//return true;
}


public function basicAccordion_clickHandler():void
{
	serve_getExpressionDatas.url='http://130.239.72.85/test2.php?primaryGene='+probeidtxt+'.1';
	serve_getExpressionDatas.send();
	//SelectVersion.selection=v1;
}

import mx.events.ItemClickEvent;

private function radioGroup_itemClick(evt:ItemClickEvent):void {
	//var now:String = new Date().toTimeString();
	if(evt.index==0 ){
		dto=new ValueObjects();
		serve_getExpressionDatas.url='http://130.239.72.85/test.php?primaryGene='+probeidtxt+'.1';
		serve_getExpressionDatas.send();
	}else{
		dto=new ValueObjects();
		serve_getExpressionDatas.url='http://130.239.72.85/test2.php?primaryGene='+probeidtxt+'.1';
		serve_getExpressionDatas.send();
	}
	
}

private function changename(item:Object, prevValue:Object, axis:CategoryAxis, categoryItem:Object):String {
	var pattern:RegExp = /_/gi;
	var str1:String=new String();
	str1=item.replace(pattern, " ");
	return str1;
	
}


protected function group1_initializeHandler(event:FlexEvent):void
{
	if(this.width<1800){
		this.height=400
	}else{
		this.height=650	
	} 
}


protected function gotohomesiteDetailsbutton_clickHandler(event:MouseEvent):void
{
	var URL:String = "http://130.239.72.85/popgenie2/transcript/"+probeidtxt+'.1';//?modeInput=Absolute&primaryGene=" + input_AGI.text;
	navigateToURL(new URLRequest(URL), "_blank");
}


